package com.actionpals.geom
{
	import flash.geom.ColorTransform;
	
	/**
	 * The ColorTrans class extends the ColorTransform class adding a collection of utilities that allows for more intuitive color manipulation.
	 * 
	 * @author Mark Walters
	 */	
	public class ColorTrans extends ColorTransform
	{
		/**
		 * Constructor.
		 * 
		 * @param redMultiplier
		 * @param greenMultiplier
		 * @param blueMultiplier
		 * @param alphaMultiplier
		 * @param redOffset
		 * @param greenOffset
		 * @param blueOffset
		 * @param alphaOffset
		 */		
		public function ColorTrans( redMultiplier:Number=1, greenMultiplier:Number=1, blueMultiplier:Number=1, alphaMultiplier:Number=1, redOffset:Number=0, greenOffset:Number=0, blueOffset:Number=0, alphaOffset:Number=0 )
		{
			super( redMultiplier, greenMultiplier, blueMultiplier, alphaMultiplier, redOffset, greenOffset, blueOffset, alphaOffset );
		}
		
		/**
		 * The scaled brightness adjustment, as a decimal between -1 and 1.
		 * Positive values lighten the color, and a value of 1 turns the color completely white.
		 * Negative values darken the color, and a value of -1 turns the color completely black.
		 */		
		public function get brightness():Number
		{
			return redOffset ? ( 1 - redMultiplier ) : ( redMultiplier - 1 );
		}
		
		/**
		 * @private
		 */		
		public function set brightness( value:Number ):void
		{
			value = Math.max( Math.min( value, 1 ), -1 );
			redMultiplier = greenMultiplier = blueMultiplier = 1 - Math.abs( value );
			redOffset = greenOffset = blueOffset = ( value > 0 ) ? value * 255 : 0;
		}
		
		/**
		 * The linear brightness adjustment, as a number between -255 and 255.
		 * Positive values lighten the color, and a value of 255 turns the color completely white.
		 * Negative values darken the color, and a value of -255 turns the color completely black.
		 */
		public function get brightnessOffset():Number
		{
			return redOffset;
		}
		
		/**
		 * @private
		 */	
		public function set brightnessOffset( value:Number ):void
		{
			redOffset = greenOffset = blueOffset = value;
		}
		
		/**
		 * The percentage to invert, as a decimal value between 0 and 1.
		 * When negative = 0, the color is its original color and no negative color is visible.
		 * When negative = 1, the color is completely negative and none of its original color is visible.
		 */
		public function get negative():Number
		{
			return ( redOffset * ( 1/255 ) );
		}
		
		/**
		 * @private
		 */
		public function set negative( value:Number ):void
		{
			redMultiplier = greenMultiplier = blueMultiplier = 1 - 2 * value;
			redOffset = greenOffset = blueOffset = value * 255;
		}
		
		/**
		 * The RGB object color value for a ColorTransform object.
		 */
		public function get rgb():RGB
		{
			return new RGB( redOffset, greenOffset, blueOffset );
		}
		
		/**
		 * @private
		 */
		public function set rgb( value:RGB ):void
		{
			color = value.color;
		}
		
		/**
		 * The tinting offset color value in the 0xRRGGBB format.
		 */
		public function get tintOffset():uint
		{
			return ( redOffset ) << 16 | ( greenOffset ) << 8 | ( blueOffset );
		}
		
		/**
		 * @private
		 */
		public function set tintOffset( value:uint ):void
		{
			var r:uint = ( value >> 16 ) & 0xFF;
			var g:uint = ( value >> 8 ) & 0xFF;
			var b:uint = value & 0xFF;
			redOffset = r;
			greenOffset = g;
			blueOffset = b;
		}
		
		/**
		 * The tint value; color and muliplier.
		 * Tint color is derived from the color offsets when retrieved, but accuracy decreases as the tint multiplier decreases.
		 * When tintMultiplier = 0, the color is its original color and no tint color is visible.
		 * When tintMultiplier = 1, the color is completely tinted and none of its original color is visible.
		 */		
		public function get tint():Tint
		{
			var multiplier:Number = ( 1 - redMultiplier );
			var color:uint = ( redOffset * multiplier ) << 16 | ( greenOffset * multiplier ) << 8 | blueOffset * multiplier;
			return new Tint( color, multiplier );
		}
		
		/**
		 * @private
		 */	
		public function set tint( value:Tint ):void
		{
			setTint( value.color, value.multiplier );
		}
		
		/**
		 * Sets the tint color and amount at the same time.
		 * 
		 * @param color The tinting color value in the 0xRRGGBB format.
		 * @param multiplier The percentage to apply the tint color, as a decimal value between 0 and 1.
		 */		
		public function setTint( color:uint, multiplier:Number ):void
		{
			var r:uint = ( color >> 16 ) & 0xFF;
			var g:uint = ( color >> 8 ) & 0xFF;
			var b:uint = color & 0xFF;
			redOffset = r * multiplier;
			greenOffset = g * multiplier;
			blueOffset = b * multiplier;
			redMultiplier = greenMultiplier = blueMultiplier = 1 - multiplier;
		}
		
		/**
		 * Resets the color to its default values.
		 */		
		public function reset():void
		{
			redMultiplier = greenMultiplier = blueMultiplier = 1;
			redOffset = greenOffset = blueOffset = 0;
		}
		
		/**
		 * Inverts the color.
		 */
		public function invert():void
		{
			redMultiplier = -redMultiplier;
			greenMultiplier = -greenMultiplier;
			blueMultiplier = -blueMultiplier;
			redOffset = 255 - redOffset;
			greenOffset = 255 - greenOffset;
			blueOffset = 255 - blueOffset;
		}
		
	}
}